{% extends 'template/jhTemplateV4.html'%}

{% block vueTemplate %}

<script type="text/html" id="app-template">
  <div>
    <v-app id="inspire" mobile-breakpoint="sm">
      <jh-menu />
      <v-main class="d-flex flex-column" style="margin-top: 60px">
        <!-- 头部内容 >>>>>>>>>>>>> -->
        <div class="pageSecondBar d-flex px-8"><div>
            <div class="appTitle pt-3" style="font-size: 18px; font-weight: 700">{{ breadcrumbs[1].fullText }}
              <!-- 帮助页按钮 -->
              <v-icon @click="isHelpPageDrawerShow = true" small>mdi-help-circle-outline</v-icon>
            </div>
            <v-breadcrumbs class="pb-3 pt-0 pl-0" :items="breadcrumbs" divider="-"></v-breadcrumbs>
          </div>
        </div>
        <!-- <<<<<<<<<<<<< 头部内容 -->

        <div class="pageBodyContainer px-8" style="flex: 1;">
          <!-- 页面内容 >>>>>>>>>>>>> -->
          <v-container class="fullScreen d-flex flex-column pa-xs-0 pa-0">
            <v-card>
            <v-row class="ma-0 pa-xs-4 align-center flex-none pt-0 " :class="{'pa-4': !isMobile, 'pb-0': !isMobile, 'pa-2': isMobile}">
          
                <v-col cols="12" xs="4" sm="4" md="4" xl="4" class="pl-0">
                  <v-btn color="success" dark class="elevation-0 mr-2" @click="doUiAction('startCreateItem')" small>新增</v-btn>
                  <span class="body-2">共{{ tableData.length }}条记录</span>
                </v-col>
                <v-spacer></v-spacer>
                <v-col cols="12" xs="3" sm="3" md="2" xl="2" class="pa-xs-0 pa-xs-2 col-sm-8-flex">
                  <v-text-field v-model="searchInput" label="表格过滤" class="cus-v-input" dense filled single-line></v-text-field>
                </v-col>
              </v-row>
              <v-data-table 
                  fixed-header
                  :headers="headers"
                  :items="tableData"
                  :search="searchInput"
                  :footer-props="{ itemsPerPageOptions: [20, 40, 60, 100, -1], itemsPerPageText: '每页行数', itemsPerPageAllText: '所有'}"
                  :items-per-page="20"
                  mobile-breakpoint="0"
                  :loading="isTableLoading"
                  checkbox-color="success" 
                  :class="{'zebraLine': showTableZebraLine }"
                  class="fixed-table-height elevation-0 mt-0 mb-xs-4 flex-fill d-flex flex-column">
                <template v-slot:footer.prepend>
                  <span class="ml-2 table-search-hint-text">共{{ tableData.length }}条记录</span>
                  <v-menu top offset-y :close-on-content-click="false">
                    <template v-slot:activator="{ on, attrs }">
                      <v-btn v-bind="attrs" v-on="on" icon>
                        <v-icon>mdi-menu</v-icon>
                      </v-btn>
                    </template>
                    <v-list>
                      <v-list-item>
                        <v-switch v-model="showTableZebraLine" label="显示斑马纹" dense flat></v-switch>
                      </v-list-item>
                    </v-list>
                  </v-menu>
                </template>
                <template v-slot:footer.page-text="pagination">
                  <span>{{pagination.pageStart}}-{{pagination.pageStop}}</span>
                  <span class="ml-1">共{{pagination.itemsLength}}条</span>
                </template>
                <template v-slot:item.downloadPath="{ item }">
                  <v-btn small class="mr-2" primary @click="doUiAction('previewFile', { item })">预览</v-btn>
                  <a href="javascript:;" @click="doUiAction('downloadFile', { item })">{{ item.downloadPath }}</a>
                </template>
                <template v-slot:item.action="{ item }">
                  <v-btn v-for="tableButton of tableButtonList" :color="tableButton.color" outlined x-small class="elevation-0 mr-2" @click="doUiAction(tableButton.action, {item, button: tableButton})">{{ tableButton.text }}</v-btn>
                </template>
              </v-data-table>
            </v-card>
          </v-container>
          
          <!-- 新增 -->
          <v-navigation-drawer v-model="isAddDrawerShow" :permanent="isAddDrawerShow" fixed temporary right width="80%" class="elevation-24">
            <v-form v-model="isFormValid" v-if="isAddDrawerShow" ref="form" lazy-validation>
              <!--抽屉标题-->
              <v-row>
                <span class="title pa-6" :class="{'pl-8': !isMobile, 'pl-6': isMobile}">新增信息</span>
              </v-row>
              <!--抽屉表单-->
              <v-row class="mt-0" :class="{'px-6': !isMobile, 'px-3': isMobile, 'pb-7': isMobile}">
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">文件</span>
                  <v-file-input v-model="addInputFile" class="cus-v-input mr-2" dense filled single-line chips label="请选择文件" ></v-file-input>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">文档类型</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="addItem['docType']"></v-text-field>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">学生名字</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="addItem['studentName']"></v-text-field>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">备注</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="addItem['remarks']"></v-text-field>
                </v-col>
          
              </v-row>
              <!--抽屉操作按钮-->
              <v-row class="mx-0 justify-end mt-4" :class="{'px-4': isMobile, 'px-6': !isMobile, 'mb-8': isMobile}">
                <v-btn color="success" @click="doUiAction('createItem')" small>保存</v-btn>
                <v-btn class="elevation-0 ml-2" @click="doUiAction('closeCreateDrawerShow')" small>取消</v-btn>
              </v-row>
            </v-form>
            <!--抽屉关闭按钮-->
            <v-btn elevation="0" color="success" fab absolute top left small tile class="drawer-close-float-btn" @click="isAddDrawerShow = false">
              <v-icon>mdi-close</v-icon>
            </v-btn>
          </v-navigation-drawer>
          
          
          <!-- 编辑抽屉 -->
          <v-navigation-drawer v-model="isEditDrawerShow" :permanent="isEditDrawerShow" fixed temporary right width="80%" class="elevation-24">
            <v-form v-model="isFormValid" v-if="isEditDrawerShow" ref="form" lazy-validation>
              <!--抽屉标题-->
              <v-row>
                <span class="title pa-6" :class="{'pl-8': !isMobile, 'pl-6': isMobile}">编辑信息</span>
              </v-row>
              <!--抽屉表单-->
              <v-row class="mt-0" :class="{'px-6': !isMobile, 'px-3': isMobile, 'pb-7': isMobile}">
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">文件</span>
                  <v-file-input v-model="editInputFile" class="cus-v-input mr-2" dense filled single-line chips label="请选择文件" ></v-file-input>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">文档类型</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="editItem['docType']"></v-text-field>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">学生名字</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="editItem['studentName']"></v-text-field>
                </v-col>
          
                <v-col cols="12" sm="12" md="4" xl="3" :class="{'pa-0': isMobile, 'px-4': isMobile, 'pt-6': isMobile}">
                  <span class="inputLabel">备注</span>
                  <v-text-field class="cus-v-input " dense filled single-line v-model="editItem['remarks']"></v-text-field>
                </v-col>
          
              </v-row>
              <!--抽屉操作按钮-->
              <v-row class="mx-0 justify-end mt-4" :class="{'px-4': isMobile, 'px-6': !isMobile, 'mb-8': isMobile}">
                <v-btn color="success" @click="doUiAction('updateItem')" small>保存</v-btn>
                <v-btn class="elevation-0 ml-2" @click="doUiAction('closeUpdateDrawerShow')" small>取消</v-btn>
              </v-row>
            </v-form>
            <!--抽屉关闭按钮-->
            <v-btn elevation="0" color="success" fab absolute top left small tile class="drawer-close-float-btn" @click="isEditDrawerShow = false">
              <v-icon>mdi-close</v-icon>
            </v-btn>
          </v-navigation-drawer>
          
            <!-- 文件预览 -->
            <v-overlay :value="previewOverlay" @click="previewOverlay = false" :opacity="0.85">
              <v-icon style="position: fixed; right: 10px; top: 5px; z-index: 50000" large color="white"
                @click="previewOverlay = false">
                mdi-close-circle
              </v-icon>
              <v-icon style="position: fixed; right: 50px; top: 5px; z-index: 50000" large color="white"
                @click="doUiAction('downloadPreviewFile')">
                mdi-download
              </v-icon>
              <iframe v-if="previewFileType === 'pdf'" :src="'/<$ ctx.app.config.duoxingBot.serverAppId $>/public/plugin/pdf/web/viewer.html?file=' + previewFileUrl" frameborder="0"
                style="width: 100vw; height: 100vh; padding: 50px 0 0 0;"></iframe>
              <v-img v-if="previewFileType === 'img'" max-height="80vw" max-width="100vw"  :src="previewFileUrl"></v-img>
            </v-overlay>
          <!-- <<<<<<<<<<<<< 页面内容 -->
        </div>

        <!-- 帮助页抽屉 >>>>>>>>>>>>> -->
        <v-navigation-drawer v-model="isHelpPageDrawerShow" fixed temporary right width="80%" class="elevation-24">
          <iframe style="border: 0" :src="`/${appInfo.appId}/pageDoc?markdownPath#1.studentFileManagement.md`" width="100%" height="100%"></iframe>
          <v-btn elevation="0" color="success" fab absolute top left small tile class="drawer-close-float-btn" @click="isHelpPageDrawerShow = false">
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </v-navigation-drawer>
        <!-- <<<<<<<<<<<<< 帮助页抽屉 -->

      </v-main>
    </v-app>

    <jhToast />
    <jhMask />
    <jhConfirmDialog />
  </div>
</script>

<div id="app">
</div>


{% endblock %}

{% block vueScript %}

<script type="module">
new Vue({
  el: '#app',
  template: '#app-template',
  vuetify: new Vuetify(),
  data: () => ({
    showTableZebraLine: true,
    // 表格相关数据
    isMobile: window.innerWidth < 600,
    isFormValid: true,
    requireRules: [
      v => !!v || 'This is required',
    ],
    constantCollection: {
    },
    overlay: false,
    fileSrc: '',
    serverSearchInput: {
      studentId: null,
      classId: null
    },
    searchInput: null,
    isTableLoading: true,
    tableData: [],
    tableDataFromBackend: [],
    headers: [
      {text: '操作', value: 'action', align: 'center', sortable: false, width: 200, class: 'fixed', cellClass: 'fixed'},
      {text: "ID", value: "id", width: 120, class: 'fixed', cellClass: 'fixed'},
      {text: "文件名", value: "filename", width: 120},
      {text: "文件路径", value: "downloadPath", width: 400},
      {text: "文件大小/KB", value: "binarySize", width: 120},
      {text: "文档类型", value: "docType", width: 120},
      {text: "学生名字", value: "studentName", width: 120},
      {text: "备注", value: "remarks", width: 120},
      {text: "操作者", value: "operationByUser", width: 120},
      {text: "操作时间", value: "operationAt", width: 250},
    ],
    tableButtonList: [
      {text: '修改', buttonType: 'edit', color: 'success', action: 'startUpdateItem'},
      {text: '删除', buttonType: 'delete', color: 'error', action: 'deleteItem'},
    ],
    isEditDrawerShow: false,
    editItem: {},
    isAddDrawerShow: false,
    addInputFile: null,
    editInputFile: null,
    addItem: {},
    previewPrefix: `/<$ ctx.app.config.appId $>/upload`,

    previewOverlay: false,
    previewFileUrl: null,
    previewFileBase64: '',
    previewFilename: '',
    previewFileType: '',
    breadcrumbs: window.breadcrumbs,
    isHelpPageDrawerShow: false,
  }),
  watch: {},
  async created() {
    await this.doUiAction('refreshTableData');
  },
  mounted() {},
  methods: {
    async doUiAction(uiActionId, uiActionData) {
        switch (uiActionId) {
          case 'refreshTableData':
            await this.refreshTableData(uiActionData);
            break;
          case 'startCreateItem':
            await this.clearItemData(uiActionData);
            await this.openCreateItemDialog(uiActionData);
            break;
          case 'closeCreateDrawerShow':
            await this.closeCreateDrawerShow(uiActionData);
            break;
          case 'closeUpdateDrawerShow':
            await this.closeUpdateDrawerShow(uiActionData);
            break;
          case 'createItem':
            await this.confirmCreateItemDialog(uiActionData);
            await this.doCreateItem(uiActionData);
            await this.refreshTableData(uiActionData);
            await this.closeCreateDrawerShow(uiActionData);
            break;
          case 'startUpdateItem':
            await this.prepareItemData(uiActionData);
            await this.openUpdateDialog(uiActionData);
            break;
          case 'updateItem':
            await this.confirmUpdateItemDialog(uiActionData);
            await this.doUpdateItem(uiActionData);
            await this.refreshTableData(uiActionData);
            await this.closeUpdateDrawerShow(uiActionData);
            break;
          case 'deleteItem':
            await this.confirmDeleteItemDialog(uiActionData);
            await this.doDeleteItem(uiActionData);
            await this.refreshTableData(uiActionData);
            break;
          case 'previewFile':
            await this.previewFile(uiActionData);
            break;
          case 'downloadFile':
            await this.downloadFile(uiActionData);
            break;
          case 'downloadPreviewFile':
            await this.downloadPreviewFile(uiActionData);
            break;
          default:
            console.error("[doUiAction] uiActionId not find", { uiActionId });
            break;
        }
    },
    // =================================uiAction 公共方法 start ======================================
    /**
     * uiActionId:  refreshTableData
     * description: ✅获取表格数据
     * main:   [{"function":"refreshTableData"}]
    */
    async refreshTableData() {
      this.isTableLoading = true;
      const serverSearchInput = _.pickBy(this.serverSearchInput, value=> !!value);
      const result = await window.jianghuAxios({
        data: {
          appData: {
            pageId: 'studentFileManagement',
            actionId: 'selectItemList',
            actionData: {},
            where: {},
            whereLike: serverSearchInput,
            orderBy: [{column: 'operationAt', order: 'desc'}]
          }
        }
      });

      this.tableDataFromBackend = result.data.appData.resultData.rows;
      this.tableData = result.data.appData.resultData.rows;
      this.isTableLoading = false;
    },
    // =================================uiAction 公共方法 end ======================================

    /**
     * uiActionId:  startCreateItem
     * description: ✅开始新增
     * main:   [{"function":"clearItemData"},{"function":"openCreateItemDialog"}]
    */
    async clearItemData() {
      this.addItem = {};
    },
    async openCreateItemDialog() {
      this.isAddDrawerShow = true;
    },

    /**
     * uiActionId:  createItem
     * description: ✅新增
     * before: [{"function":"confirmCreateItemDialog"}]
     * main:   [{"function":"doCreateItem"},{"function":"refreshTableData"}]
     * after:  [{"function":"closeCreateDrawerShow"}]
    */
    async confirmCreateItemDialog() {
      if (await window.confirmDialog({title: "新增", content: "确定新增吗？"}) === false) {
          throw new Error("[confirmCreateFormDialog] 否");
      }
    },
    async doCreateItem() {
      const { docType, studentName, remarks } = this.addItem;
      const _this = this;
      const result = await window.jianghuAxios.httpUploadByStream({ file: this.addInputFile, fileDirectory: 'testFile',
        onProgress: (total, loaded) => {
          let progress = Number((loaded * 100 / total).toFixed(2))
          window.vtoast.loading(`文件上传进度${progress}%`);
          if (progress === 100) {
            window.vtoast.success('文件上传成功');
          }
        }
      });
      const { status } = result.data;
      const { filename, downloadPath, binarySize } = result.data.appData.resultData;
      if (status === 'success') {
        await window.vtoast.loading("新增数据");
        await window.jianghuAxios({
          data: {
            appData: {
              pageId: 'studentFileManagement',
              actionId: 'insertItem',
              actionData: { docType, studentName, remarks, filename, downloadPath, binarySize}
            }
          }
        })
        await window.vtoast.success("新增数据成功");
      } else {
        await window.vtoast.fail("文件上传失败");
      }

    },
    async closeCreateDrawerShow() {
      this.isAddDrawerShow = false;
      this.addInputFile = null;
    },

    /**
     * uiActionId:  startUpdateItem
     * description: ✅开始更新
     * main:   [{"function":"prepareItemData"},{"function":"openUpdateDialog"}]
    */
    async prepareItemData({item}) {
      this.editItem = {...item};
      this.editInputFile = new File([new Blob()], item.filename);
    },
    async openUpdateDialog() {
      this.isEditDrawerShow = true;
    },
    /**
     * uiActionId:  updateItem
     * description: ✅更新
     * before: [{"function":"confirmUpdateItemDialog"}]
     * main:   [{"function":"doUpdateItem"},{"function":"refreshTableData"}]
     * after:  [{"function":"closeUpdateDrawerShow"}]
    */
    async confirmUpdateItemDialog() {
      if (await window.confirmDialog({title: "修改", content: "确定修改吗？"}) === false) {
          throw new Error("[confirmUpdateItemDialog] 否");
      }
    },
    async doUpdateItem() {
      const { id, docType, studentName, remarks } = this.editItem;
      const updateParam = { docType, studentName, remarks };
      if (this.editInputFile && this.editInputFile.size) {
        const result =  await window.jianghuAxios.httpUploadByStream({ file: this.editInputFile, fileDirectory: 'testFile',
          onProgress: (total, loaded) => {
            let progress = Number((loaded * 100 / total).toFixed(2))
            window.vtoast.loading(`文件上传进度${progress}%`);
            if (progress === 100) {
              window.vtoast.success('文件上传成功');
            }
          }
        })
        const { status } = result.data
        const { filename, downloadPath, binarySize } = result.data.appData.resultData
        
        updateParam.filename = filename;
        updateParam.downloadPath = downloadPath;
        updateParam.binarySize = binarySize;
      }

      await window.vtoast.loading("修改数据");
      await window.jianghuAxios({
        data: {
          appData: {
            pageId: 'studentFileManagement',
            actionId: 'updateItem',
            actionData: updateParam,
            where: { id }
          }
        }
      })
      await window.vtoast.success("修改数据成功");
    },
    async closeUpdateDrawerShow() {
      this.isEditDrawerShow = false;
      this.updateInputFile = null;
    },

    /**
     * uiActionId:  deleteItem
     * description: ✅删除
     * before: [{"function":"confirmDeleteItemDialog"}]
     * main:   [{"function":"doDeleteItem"},{"function":"refreshTableData"}]
    */
    async confirmDeleteItemDialog() {
      if (await window.confirmDialog({title: "删除", content: "确定删除吗？"}) === false) {
          throw new Error("[confirmDeleteItemDialog] 否");
      }
    },
    async doDeleteItem({item}) {
      const { id } = item;
      await window.vtoast.loading("删除数据");
      await window.jianghuAxios({
        data: {
          appData: {
            pageId: 'studentFileManagement',
            actionId: 'deleteItem',
            actionData: {},
            where: { id: id }
          }
        }
      });
      await window.vtoast.success("删除数据成功");
    },

    /**
     * uiActionId: downloadFile
     * description: ✅下载
     * main:   [{"function":"downloadFile"}]
     */
     async downloadFile({ item }) {
      const { filename, downloadPath } = item;
      window.vtoast.loading('文件下载进度0.00%');
      const buffer = await window.jianghuAxios.httpDownloadByStream({ downloadPath, filename,
        onProgress: (total, loaded)=> {
          const progress = Number((loaded * 100 / total).toFixed(2));
          window.vtoast.loading(`文件下载进度${progress}%`);
          if (progress === 100) {
            window.vtoast.success('文件下载成功');
          }
        }
      }).catch(err => {
        window.vtoast.fail({ message: err.errorReason });
        throw err;
      });
      window.jianghuAxios.downloadBufferToChrome({ buffer, filename });
    },

    /**
     * uiActionId: previewFile
     * description: ✅预览文件
     * main:   [{"function":"previewFile"}]
     */
    async previewFile({ item }) {
      const { filename, downloadPath, binarySize } = item;
      if (binarySize > 7 * 1024) {
        window.vtoast.fail('文件大于7M, 不支持预览!');
        // 中断uiAction
        return false;
      }
      this.previewFileType = null;
      if (/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(filename)) {
        this.previewFileType = 'img';
        this.previewFileUrl = `/<$ ctx.app.config.appId $>/upload${downloadPath}`;
      }
      if (/\.(pdf|PDF)$/.test(filename)) {
        this.previewFileType = 'pdf';
        this.previewFileUrl = '/<$ ctx.app.config.appId $>/public/plugin/pdf/web/viewer.html?file=' + encodeURIComponent(`/<$ ctx.app.config.appId $>/upload${downloadPath}`);
      }
      this.previewFilename = filename;
      this.previewOverlay = true;
    },

    /**
     * uiActionId: downloadPreviewFile
     * description: ✅下载正在预览的文件
     * main:   [{"function":"downloadPreviewFile"}]
    */
    async downloadPreviewFile() {
      const oReq = new XMLHttpRequest();
      const url = this.previewFileUrl;
      const filename = this.previewFilename;
      oReq.open("GET", url, true);
      oReq.responseType = "arraybuffer";
      oReq.onprogress = function (event) {
        if (event.lengthComputable) {
          const progress = Number((event.loaded * 100 / event.total).toFixed(2));
          window.vtoast.loading(`文件下载进度${progress}%`);
          if (progress === 100) {
            window.vtoast.success('文件下载成功');
          }
        }
      }
      oReq.onload = function (oEvent) {
        const buffer = oReq.response;
        let url = window.URL.createObjectURL(new Blob( [buffer], {type: "arraybuffer"}) )
        const link = document.createElement('a');
        link.style.display = 'none';
        link.href = url;
        link.setAttribute('download', filename);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      };
      oReq.send(null);
    },
  }
})
</script>

<style scoped>
</style>
{% endblock %}
